/**
 * Created by Richard Radlherr.
 * Date: 13.07.2006 19:17
 */

using System;
using System.Collections.Generic;
using System.IO;
using TagTool.Core;

namespace TagTool.GraphicTypes
{
	[Serializable()]
	public class Scene : Shape
	{
		private List<Shape> shapes = new List<Shape>();
				
		public Scene()
		{
		}
		
		public override void Dispose()
		{
			lock(shapes)
			{
				foreach(Shape s in shapes)
				{
					s.Dispose();
				}
			}
			base.Dispose();
		}
		
		public Shape this[int index]
		{
			get { return shapes[index]; }
		}
		
		public override double Alpha
		{
			set { 
				if (value != alpha)
				{
					lock(shapes)
					{
						alpha = value;
						foreach(Shape s in shapes)
						{
							s.Alpha = alpha;
						}	
					}
				}
			}
		}
		
		public List<Shape> Shapes
		{
			get { return shapes; }
			set
			{
				foreach(Shape s in shapes)
				{
					s.Dispose();
				}
				shapes = value;
				Update();
			}
		}
		
		public void Add(Shape shape)
		{
			lock(shapes)
			{
				shape.FadeStep = 0.05;
				shapes.Add(shape);
				Update();
			}
		}
		
		public void RemoveAt(int index)
		{
			lock(shapes)
			{
				shapes.RemoveAt(index);
				Update();
			}
		}
		
		public void Remove(Shape shape)
		{
			lock (shapes)
			{
				shapes.Remove(shape);
				Update();
			}
		}
		
		public void Clear()
		{
			lock(shapes)
			{
				foreach(Shape s in shapes)
				{
					s.Dispose();
				}
				shapes.Clear();
				Update();
			}
		}
		
		protected override void Compile()
		{
			
		}

		public override void Render()
		{
			if (glList != 0)
			{
				glPushMatrix();
				
				glScaled(scale.X, scale.Y, scale.Z);
				glTranslated(translate.X, translate.Y, translate.Z);
				glRotated(angle, rotate.X, rotate.Y, rotate.Z);

				lock(shapes)
				{
					foreach(Shape s in shapes)
					{
						s.Render();
					}
				}
				
				glPopMatrix();
			}
		}
		
		public override void Move()
		{
			lock(shapes)
			{
				foreach(Shape s in shapes)
				{
					s.Move();
				}
				base.Move();
				
			}
		}
		
		public override void Save(StreamWriter writer)
		{
			long start;
			long act;
			try {
				lock(shapes)
				{
					// Scene container
					// Header
					writer.WriteLine("Scene");
					
					// Length
					start = writer.BaseStream.Position;
					writer.WriteLine(String.Format("{0:000000000000}", 0));
					// Data (Tags)
					foreach(Shape s in shapes)
					{
						s.Save(writer);
						writer.Flush();
					}
					
					// Length
					act = writer.BaseStream.Position;
					writer.BaseStream.Seek(start, 0);
					writer.WriteLine(String.Format("{0:000000000000}", act - start));
					
					// set to end of file
					writer.BaseStream.Seek(act, 0);
					
				}
				
			} catch (Exception)
			{
				// eat this fucking exception (hrhr)
			}
		}
		
		public override void Load(StreamReader reader)
		{
			try {
				Dispose();
				
				bool stop = false;
				do
				{
					long l = reader.BaseStream.Position;
					if (ReadHeader(reader, false, "Tag"))
					{
						Tag t = new Tag();
						t.Load(reader);
						shapes.Add(t);
					}
					else
					{
						stop = true;
					}
				}
				while (!stop);
					
			} catch (Exception ex)
			{
				Console.WriteLine("Error on loading scene" + ex.StackTrace);
			}
		}
		
	}
	
}
